use data::tables::WeaponID;
use proto::PlayerSyncScNotify;

use crate::ServerState;

use super::ArgSlice;

pub async fn add_weapon(
    args: ArgSlice<'_>,
    state: &ServerState,
) -> Result<String, Box<dyn std::error::Error>> {
    const USAGE: &str = "Usage: item add_weapon [player_uid] [weapon_id]";

    if args.len() != 2 {
        return Ok(USAGE.to_string());
    }

    let uid = args[0].parse::<u32>()?;
    let weapon_id = args[1].parse::<u32>()?;
    let Ok(weapon_id) = WeaponID::new(weapon_id) else {
        return Ok(format!("weapon with id {weapon_id} doesn't exist"));
    };

    let Some(player_lock) = state.player_mgr.get_player(uid).await else {
        return Ok(String::from("player not found"));
    };

    let (session_id, weapon_uid, item_sync) = {
        let mut player = player_lock.lock().await;
        let uid = player.item_model.add_weapon(weapon_id);

        (
            player.current_session_id(),
            uid.value(),
            player.item_model.item_sync(),
        )
    };

    if let Some(session) = session_id.map(|id| state.session_mgr.get(id)).flatten() {
        session
            .notify(PlayerSyncScNotify {
                item_sync: Some(item_sync),
                ..Default::default()
            })
            .await?;
    } else {
        state.player_mgr.save_and_remove(uid).await;
    }

    Ok(format!("successfully added weapon, item uid: {weapon_uid}"))
}
